import matplotlib.pyplot as plt
from matplotlib import cm
import pandas as pd
import os

class Analysis:
    def __init__(self, config:dict):
        self.config = config
        self.config["dataset_name"] = \
            config["dataset_path"].rsplit("/", 1)[-1].rsplit(".")[0]
        self.config["report_dir"] = os.path.join(
            self.config["output_dir"],
            self.config["dataset_name"])

        if not os.path.exists(self.config["report_dir"]):
            os.makedirs(self.config["report_dir"])

        # self.dataset = pd.read_csv(self.config["dataset_path"], nrows=10*100)
        self.dataset = pd.read_csv(self.config["dataset_path"])

        # remove features with 0 std
        self.dataset = self.dataset.loc[:, self.dataset.std() > 0]

    def describe(self) -> str:
        """Output tatic information of dataset.

        Returns:
            describe_file_path: A csv file contains dataset's static information.
        """
        describe_file_path = os.path.join(self.config["report_dir"], "describe.csv")
        self.dataset.describe().to_csv(describe_file_path)

        print("describe file was saved at ", describe_file_path)

        return describe_file_path

    def shape(self):
        """Print shape of dataset (row, col).
        """
        print("-" * 50)
        print("shape:")
        print(self.dataset.shape)
        print("-" * 50)

    def show_type(self):
        """Print features' type.
        """
        print("-" * 50)
        print("type:")
        pd.set_option("display.max_rows", 100)
        print(self.dataset.dtypes)
        print("-" * 50)

    def show_distribution(self):
        """Show label distribution.
        """
        label_col = self.dataset.shape[1]
        print(self.dataset.groupby("label").size())

    def histogram(self) -> str:
        """Show and save histogram.

        Returns:
            hist_path: Path to histogram.
        """
        hist_path = os.path.join(self.config["report_dir"], "hsit.svg")
        features = self.dataset.iloc[:, :-1]
        features.hist(sharex=False, sharey=False, xlabelsize=1, ylabelsize=1,
            figsize=(20, 20), layout=(8, 6))
        plt.savefig(hist_path, format="svg")
        plt.show()

        return hist_path

    def density(self) -> str:
        """Show and save density (KDE) figure.

        Make sure that the features' std not equal to 0.

        Returns:
            density_path: Path to density figure.
        """
        density_path = os.path.join(self.config["report_dir"], "density.svg")
        features = self.dataset.iloc[:, :-1]
        # print(features.iloc[1].index.tolist())
        features.plot(
            kind="density",
            title=features.iloc[1].index.tolist(),
            subplots=True, 
            figsize=(20, 20),
            layout=(8, 6),
            sharex=False,
            legend=False,
            fontsize=1
        )
        plt.savefig(density_path, format="svg")
        plt.show()

        return density_path

    def correlation(self) -> str:
        """Show pairwise correlation of column.

        Returns:
            corr_path: Path to corrlation figure.
        """
        corr_path = os.path.join(self.config["report_dir"], "corr.png")
        features = self.dataset.iloc[:, :-1]
        # fig = plt.figure(figsize=(20, 20))
        fig = plt.figure()

        ax = fig.add_subplot(111)
        cax = ax.matshow(features.corr(), vmin=-1, vmax=1, interpolation="none", cmap=cm.coolwarm)
        fig.colorbar(cax)

        plt.savefig(corr_path, format="png")
        plt.show()

def main():
    config = {
        "dataset_path": "data/dataset/dataset-nfstream-20220304210805-shuffled.csv",
        "output_dir": "data/dataset_report"
    }

    a = Analysis(config)
    # a.describe()
    # a.shape()
    # a.show_type()
    # a.show_distribution()
    # a.histogram()
    # a.density()
    a.correlation()
    pass

if __name__ == "__main__":
    main()